package edu.gyc.hishiro.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import edu.gyc.hishiro.model.SysRolePermission;
import edu.gyc.hishiro.model.UserInfo;
import edu.gyc.hishiro.service.SysRolePermissionService;
import edu.gyc.hishiro.service.UserInfoService;
import edu.gyc.hishiro.shiro.MakeMd5;
import edu.gyc.hishiro.shiro.ShiroRealm;
import edu.gyc.hishiro.shiro.ShiroSessionListener;
import edu.gyc.hishiro.utils.YzmUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;

import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ls
 * @since 2021-01-04
 */
@Controller
@Slf4j
public class UserInfoController {

    @Autowired
    UserInfoService userInfoService;

    @GetMapping("/login")
    public String login() {


        return "/";
    }

    @Autowired
    private ShiroSessionListener shiroSessionListener;

    @PostMapping("/login")
    public String dologin(UserInfo user,String yzm, HttpServletRequest request) {

        String yzmSession = (String) request.getSession().getAttribute("yzm");
        if (null == yzmSession || !yzmSession.equalsIgnoreCase(yzm)) {
            request.setAttribute("msg", "验证码不正确！");
            return "/";
        }

        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(usernamePasswordToken);
            UserInfo userInfo = (UserInfo) subject.getPrincipal();
            userInfo.setPassword("");
            subject.getSession().setAttribute("user", userInfo);
            request.getSession().setAttribute("menus",userInfoService.getUserMenu(userInfo.getUid()));
            //显示在线人数，目前在页面上未显示，以后用
            request.getSession().setAttribute("count",shiroSessionListener.getSessionCount());

        } catch (Exception e) {
            //登录失败从request中获取shiro处理的异常信息 shiroLoginFailure:就是shiro异常类的全类名
            String exception = (String) request.getAttribute("shiroLoginFailure");
            request.setAttribute("msg", e.getMessage());
            //返回登录页面
            return "login";
        }
        return "menu";
    }



    /**
     * 登出  这个方法没用到,用的是shiro默认的logout
     * 在ShiroConfig//logout是shiro提供的过滤器
     * filterChainDefinitionMap.put("/logout", "logout");
     * 若要使用可以注释上面这个方法，就可调用下面方法注销用户
     */

    @RequestMapping("/logout")
    public String logout() {

        Subject subject = SecurityUtils.getSubject();
        log.info(((UserInfo) subject.getPrincipal()).getUsername() + "退出系统.");
        subject.logout();

//注销使用重定向比较好，请求转发会导致org.apache.shiro.session.UnknownSessionException
        return "redirect:/";
    }

    @GetMapping("/unauthorized")
    public String unauthorized() {


        return "unauthorized";
    }

    @RequestMapping("/yzm.jpg")
    public void getYzm(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置相应类型,告诉浏览器输出的内容为图片
        response.setContentType("image/jpeg");
        // 不缓存此内容
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);
        try {

            HttpSession session = request.getSession();

            YzmUtil tool = new YzmUtil();
            StringBuffer code = new StringBuffer();
            BufferedImage image = tool.genRandomCodeImage(code);
            session.removeAttribute("yzm");
            session.setAttribute("yzm", code.toString());

            // 将内存中的图片通过流动形式输出到客户端
            ImageIO.write(image, "JPEG", response.getOutputStream());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/reg")
    public String reg() {
        return "/reg";
    }

    @PostMapping("/reg")
    public String doreg(String username, String password, Model model) {
        boolean isSuccess=false;
        String msg = "";

        if (username.isBlank() || password.isBlank() ) {
            model.addAttribute("isSuccess", isSuccess);
          return "/reg";
        }
        UserInfo userInfo=userInfoService.lambdaQuery().eq(UserInfo::getUsername,username).one();
        if (userInfo != null) {
            msg="用户名已被使用，换一个吧！";
            model.addAttribute("msg", msg);
            model.addAttribute("isSuccess", isSuccess);
            return "/reg";
        }

        String salt = RandomStringUtils.randomAlphabetic(6);
        String newpass = MakeMd5.make(password,salt);

        UserInfo newUser=new UserInfo();
        newUser.setUsername(username);
        newUser.setPassword(newpass);
        newUser.setSalt(salt);
        userInfoService.save(newUser);
        msg="恭喜你注册成功！";
        model.addAttribute("msg", msg);
        isSuccess=true;
        model.addAttribute("isSuccess", isSuccess);
        return "/reg";

    }

    @Autowired
    SysRolePermissionService rolePermissionService;

    @RequestMapping("/addStuDelPermission")
    @ResponseBody
    public String addPermisstion() {
        //给role id 为1的角色，增加stu 删除权限 ，为 3号permission
        rolePermissionService.save(new SysRolePermission(1, 3));
        DefaultWebSecurityManager securityManager=(DefaultWebSecurityManager)SecurityUtils.getSecurityManager();
        ShiroRealm shiroRealm=(ShiroRealm)securityManager.getRealms().iterator().next();

        shiroRealm.clearAllCache();
        return "给admin角色添加学生删除权限成功！";

    }

    @RequestMapping("/delPermissionCache")
    @ResponseBody
    public String delPermisstion() {
//        //删除role id 为1的角色，增加stu 删除权限 ，为 3号permission
//        SysRolePermission rolePermission=rolePermissionService.lambdaQuery().eq(SysRolePermission::getRoleId, 1)
//                .eq(SysRolePermission::getPermissionId, 3).one();
//        rolePermissionService.r
        DefaultWebSecurityManager securityManager=(DefaultWebSecurityManager)SecurityUtils.getSecurityManager();
        ShiroRealm shiroRealm=(ShiroRealm)securityManager.getRealms().iterator().next();

        shiroRealm.clearAllCache();
        return "清除权限缓存成功！";

    }
}

